/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sqlcommand;

import data.Row;
import java.util.ArrayList;

/**
 * Lop duoc su dung khi dieu kien gom nhieu gia tri and, or.. lai voi nhau
 *
 * @author Quang
 */
public class MutileCondition extends JConditions {

    private static String[] keyWordCompareCondition = {
        "AND",
        "OR",};
    private String sqlCondition;
    private ArrayList<SingleCondition> singleCondition;
    private ArrayList<String> connectWord;
    private int nTable;

    public MutileCondition(String condition, int numberTable) {
        sqlCondition = Command.standardizeString(condition);
        nTable = numberTable;
        init();

    }

    private void init() {
        singleCondition = new ArrayList<SingleCondition>();
        connectWord = new ArrayList<String>();
    }

    public MutileCondition() {
        init();
    }

    /**
     * phan tich chuoi sqlCondition ra thanh tung cac condition nho va cac tu
     * ket noi
     */
    public void analyse(MyError err) {
        Boolean flag = false;//kiem tra xem day co phai la cau lenh phuc k?

        for (int i = 0; i < keyWordCompareCondition.length; i++) {
            if (Command.indexOfString(getSqlCondition(),keyWordCompareCondition[i]) != -1) {
                flag = true;
            }
        }
        if (!flag) {
            SingleCondition sc = new SingleCondition(nTable);
            sc = (SingleCondition) sc.String2Condition(getSqlCondition(),err);
            if (sc != null) {
                getSingleCondition().add(sc);
                return;
            }
        }
        // tim vi tri cac tu khoa trong cau dieu kien
        ArrayList<Integer> posKeyWord = new ArrayList<Integer>();
        ArrayList<Integer> sizeKeyWord = new ArrayList<Integer>();

        //lay danh sach
        StringBuffer str = new StringBuffer(getSqlCondition());
        
            while (str.length() > 0) {
                int pos = -1;
                for (int i = 0; i < keyWordCompareCondition.length; i++) {
                    pos = Command.indexOfString(str,keyWordCompareCondition[i]);
                    if (pos != -1) {
                        posKeyWord.add(pos);
                        int size = keyWordCompareCondition[i].length();
                        getConnectWord().add(keyWordCompareCondition[i]);
                        sizeKeyWord.add(size);

                        String temp = str.substring(0, pos);
                        SingleCondition sc = new SingleCondition(nTable);
                        sc = (SingleCondition) sc.String2Condition(temp,err);
                        getSingleCondition().add(sc);

                        str.delete(0, pos + size);
                        break;
                    }
                }
                if (-1 == pos) {
                    SingleCondition sc = new SingleCondition(nTable);
                    sc = (SingleCondition) sc.String2Condition(str.toString(),err);
                    getSingleCondition().add(sc);

                    break;
                }

            }
        


    }

    public Boolean compareCondition(Boolean b1, Boolean b2, String connect, MyError err) {
        connect = connect.toUpperCase();
        Boolean flag = false;

        if ("AND".equals(connect)) {
            if (b1 && b2) {
                return true;
            } else {
                return false;
            }
        }

        if ("OR".equals(connect)) {
            if (b1 || b2) {
                return true;
            }
            return false;
        }

        if ("NOT".equals(connect)) {
            return !b1;
        }

        err.setError("Error! khong ho tro phep ket noi nay!");
        return false;
    }

    @Override
    public Boolean InitValue(MyError err){
        init();
        analyse(err);
         if(err.getError() != null){
            System.out.println(err.getError());
            return false;
        }        
        return true;
    }
    @Override
    public Boolean compare(Row row, MyError err) {
        
       if (singleCondition.size() == 1) {
            return singleCondition.get(0).compare(row, err);
        }
        SingleCondition sc0 = singleCondition.get(0);
        SingleCondition sc1 = singleCondition.get(1);
        Boolean[] b = new Boolean[connectWord.size()];
        
        Boolean t1; 
        Boolean t2;
        if (1 == nTable) {
            t1 = sc0.compare(row, err);
            t2 = sc1.compare(row, err);
        } else {
            t1 = sc0.compareFor2Table(row, err);
            t2 = sc1.compareFor2Table(row, err);
        }

        b[0] = compareCondition(t1, t2, connectWord.get(0), err);

        for (int i = 2; i < singleCondition.size(); i++) {
            SingleCondition sc = singleCondition.get(i);
            
            b[i - 1] = compareCondition(b[i - 2], sc.compare(row, err), connectWord.get(i - 1), err);
        }

        return b[connectWord.size() - 1];
    }

    /**
     * @return the sqlCondition
     */
    public String getSqlCondition() {
        return sqlCondition;
    }

    /**
     * @return the singleCondition
     */
    public ArrayList<SingleCondition> getSingleCondition() {
        return singleCondition;
    }

    /**
     * @return the connectWord
     */
    public ArrayList<String> getConnectWord() {
        return connectWord;
    }
}
